import domain.Person;

import java.lang.reflect.Field;

/**
 * 成员变量：Field
 * 获取功能：
 * 1. 获取成员变量们
 * Field[] getFields()
 * Field getField(String name)
 * Field[] getDeclaredFields()
 * Field getDeclaredField(String name)
 * 操作：
 * 1. 设置值
 * * void set(Object obj, Object value)：传递一个具体的对象，设置该对象中对应成员变量的值
 * 2. 获取值
 * * Object get(Object obj)：传递一个具体的对象，返回该对象中需要获取的成员变量的值
 * 3. 忽略访问权限修饰符的安全检查
 * * setAccessible(boolean flag)：传递参数为true时暴力反射，无视权限修饰符。
 */
//我定义的Person类中成员变量只有：public String a
public class ClassFunction_Field {
    public static void main(String[] args) {
        try {
            //0.获取Person类的Class对象
            Class personClass = Person.class;
            //1.Field[] getFields()：获取所有public修饰的成员变量
            Field[] fields = personClass.getFields();
            for (Field field : fields) {
                System.out.println(field);//public java.lang.String domain.Person.a
            }

            //2.Field getField(String name)：获取指定名称的public修饰的成员变量
            Field a = personClass.getField("a");
            //3.获取变量a的值
            Person p = new Person();
            Object value = a.get(p);
            System.out.println(value);//null
            //4.设置变量a的值
            a.set(p, "XHH&YDD");
            System.out.println(a.get(p));//XHH&YDD

            //5.Field[] getDeclaredFields()：获取所有的成员变量，不考虑修饰符
            Field[] allFields = personClass.getDeclaredFields();
            for (Field field : allFields) {
                System.out.println(field);
                //输出结果：
                //private java.lang.String domain.Person.name
                //private int domain.Person.age
                //public java.lang.String domain.Person.a
                //protected java.lang.String domain.Person.b
                //java.lang.String domain.Person.c
                //private java.lang.String domain.Person.d
            }

            //6.Field getDeclaredField(String name)：获取指定名称的成员变量，对于非public修饰的变量，先调用setAccessible(true)忽略访问权限修饰符的安全检查，否则抛异常。
            Field age = personClass.getDeclaredField("age");//此处age是private修饰的
            //7.忽略访问权限修饰符的安全检查，否则抛异常
            age.setAccessible(true);
            //8.获取变量age的值
            System.out.println(age.get(p));//0
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
